#include "g711decoder.h"

int16_t G711Decoder::decodeMuLaw(uint8_t muLawByte) {
    muLawByte = ~muLawByte;
    int sign = (muLawByte & 0x80) ? -1 : 1;
    int exponent = (muLawByte >> 4) & 0x07;
    int mantissa = muLawByte & 0x0F;
    int magnitude = ((0x100 | (mantissa << 4)) << exponent) - 132;
    return sign * magnitude;
}

int16_t G711Decoder::decodeALaw(uint8_t aLawByte) {
    aLawByte ^= 0x55;
    int sign = (aLawByte & 0x80) ? -1 : 1;
    int exponent = (aLawByte >> 4) & 0x07;
    int mantissa = aLawByte & 0x0F;
    int magnitude = ((0x100 | (mantissa << 4)) << exponent) - 132;
    return sign * magnitude;
}

int16_t G711Decoder::decodeALaw1(uint8_t a_val)
{

    int t = 0; // 初始化解码后的 PCM 值
        a_val ^= 0x55; // 与 0x55 异或

        t = (a_val & 0x0F) << 4; // 取低 4 位，并左移 4 位
        int seg = ((unsigned)a_val & 0x70) >> 4; // 取段位值

        // 根据段位值计算 PCM 值
        switch (seg) {
        case 0:
            t += 8;
            break;
        case 1:
            t += 0x108;
            break;
        default:
            t += 0x108;
            t <<= seg - 1;
        }
        return (a_val & 0x80) ? t : -t; // 如果符号位为 1，则返回负值，否则返回正值

}

int16_t G711Decoder::decodeALaw2(uint8_t a_val)
{
    return aLawDecompressTable[a_val];
}

int16_t G711Decoder::decodeALaw3(uint8_t aLawByte)
{
    aLawByte ^= 0x55;

    int sign = (aLawByte & 0x80) ? -1 : 1;
    int exponent = (aLawByte & 0x70) >> 4;
    int mantissa = aLawByte & 0x0F;

    int16_t pcm_val;
    if (exponent == 0) {
        pcm_val = (mantissa << 4) + 8;
    } else {
        pcm_val = ((mantissa << 4) + 0x108) << (exponent - 1);
    }
    pcm_val *= sign;

    return pcm_val;
}
